Notebook realizado por Roger Rey Mesa
https://www.kaggle.com/shivamb/netflix-shows?select=netflix_titles.csv
Netflix, es una empresa de entretenimiento y un servicio por suscripción estadounidense que opera a nivel mundial y cuyo servicio principal es la distribución de contenidos audiovisuales a través de una plataforma en línea o servicio de video bajo demanda por streaming.Es una aplicación que crece cada vez más y más rápido con su popularidad, sus espectáculos y su contenido.
Este notebook trata de realizar un estudio avanzado a través de sus datos y una amplia gama de diferentes gráficos y visuales.

Este dataset consiste en series, programas de televisión y películas disponibles en Netflix desde su inicio hasta 2019. El conjunto de datos se recoge de Flixable que es un motor de búsqueda de terceros de Netflix.
En 2018, publicaron un interesante informe que muestra que el número de programas de televisión en Netflix casi se ha triplicado desde 2010. El número de películas del servicio de streaming ha disminuido en más de 2.000 títulos desde 2010, mientras que el número de programas de televisión casi se ha triplicado. Será interesante explorar lo que el resto de las percepciones se pueden obtener del mismo conjunto de datos.
El objetivo es realizar un estudio avanzado sobre todos los datos que disponemos. Empezaremos con un apartado de EDA donde podremos obvservar todas las conclusiones a extraer del estudio inical. Seguiremos con un apartado de preprocessing para limpiar los valors no servibles o outliers que disponemos en nuestra base de datos i normalizaremos los datos en caso que sea necesario para poder tratar los de mejor manera en el siguiente apartado. Finalizaremos con un punto de aplicación de modelos para realizar una classificación de los datos y extraeremos conclusiones sobre todo el estudio realizado con este dataset.
El siguiente código, incluye todas las librerias necesarias para este estudio y lee la base de datos.
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import seaborn as sns
from sklearn import preprocessing
import matplotlib.pyplot as plt
%matplotlib inline
import plotly.graph_objects as go
from plotly.offline import init_notebook_mode, iplot
import os
netflix = pd.read_csv('netflix_titles.csv')
print("Dimensionalidad de la BBDD:", netflix.shape)
Dimensionalidad de la BBDD: (6234, 12)
El dataset contiene 6234 muestras y disponemos de 12 atributos.
Mostramos todos los atributos que dispone la base de datos y el tipo.
netflix.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 6234 entries, 0 to 6233 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 show_id 6234 non-null int64 1 type 6234 non-null object 2 title 6234 non-null object 3 director 4265 non-null object 4 cast 5664 non-null object 5 country 5758 non-null object 6 date_added 6223 non-null object 7 release_year 6234 non-null int64 8 rating 6224 non-null object 9 duration 6234 non-null object 10 listed_in 6234 non-null object 11 description 6234 non-null object dtypes: int64(2), object(10) memory usage: 584.6+ KB
Los atributos de muestras de la base de datos son los siguientes:
print("Para visualitzar las primeras 5 muestras de la BBDD:")
dataset.head()
Para visualitzar las primeras 5 muestras de la BBDD:
| show_id | type | title | director | cast | country | date_added | release_year | rating | duration | listed_in | description | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 81145628 | Movie | Norm of the North: King Sized Adventure | Richard Finn, Tim Maltby | Alan Marriott, Andrew Toth, Brian Dobson, Cole... | United States, India, South Korea, China | September 9, 2019 | 2019 | TV-PG | 90 min | Children & Family Movies, Comedies | Before planning an awesome wedding for his gra... |
| 1 | 80117401 | Movie | Jandino: Whatever it Takes | NaN | Jandino Asporaat | United Kingdom | September 9, 2016 | 2016 | TV-MA | 94 min | Stand-Up Comedy | Jandino Asporaat riffs on the challenges of ra... |
| 2 | 70234439 | TV Show | Transformers Prime | NaN | Peter Cullen, Sumalee Montano, Frank Welker, J... | United States | September 8, 2018 | 2013 | TV-Y7-FV | 1 Season | Kids' TV | With the help of three human allies, the Autob... |
| 3 | 80058654 | TV Show | Transformers: Robots in Disguise | NaN | Will Friedle, Darren Criss, Constance Zimmer, ... | United States | September 8, 2018 | 2016 | TV-Y7 | 1 Season | Kids' TV | When a prison ship crash unleashes hundreds of... |
| 4 | 80125979 | Movie | #realityhigh | Fernando Lebrija | Nesta Cooper, Kate Walsh, John Michael Higgins... | United States | September 8, 2017 | 2017 | TV-14 | 99 min | Comedies | When nerdy high schooler Dani finally attracts... |
print("Para ver estadísticas de los atributos numéricos de la BBDD:")
dataset.describe()
Para ver estadísticas de los atributos numéricos de la BBDD:
| show_id | release_year | |
|---|---|---|
| count | 6.234000e+03 | 6234.00000 |
| mean | 7.670368e+07 | 2013.35932 |
| std | 1.094296e+07 | 8.81162 |
| min | 2.477470e+05 | 1925.00000 |
| 25% | 8.003580e+07 | 2013.00000 |
| 50% | 8.016337e+07 | 2016.00000 |
| 75% | 8.024489e+07 | 2018.00000 |
| max | 8.123573e+07 | 2020.00000 |
Como hemos podido observar en las tablas anteriores, la mayoria de atributos de este dataset son de formato texto excepto los atributos "show_id" y "release_year" que són numéricos. Esto nos complica más el estudio ja que los datos en formato texto són mas dificiles de tratar y se han de tratar de una manera más específica.
print("Comprovamos si hay valores no existentes o inservibles:")
print("\n--------------------- DATASET NETFLIX ---------------------")
print(netflix.isnull().sum())
Comprovamos si hay valores no existentes o inservibles: --------------------- DATASET NETFLIX --------------------- show_id 0 type 0 title 0 director 1969 cast 570 country 476 date_added 11 release_year 0 rating 10 duration 0 listed_in 0 description 0 dtype: int64
Una vez comprobado, observamos como el dataset dispone de más de 2000 muestras que valores inservibles, por lo tanto deberemos eliminar estas muestras para poder empezar a tratar los datos y de esta manera evitar resultados inconcluentes o sin sentido.
Continuamos con nuestro estudio y empezamos a mostrar las primeras gràficas, en este caso mostramos el atributo "type" que nos indica de que tipo de show són los elementos que tenemos en Netflix, pueden ser series o películas. Como podemos apreciar, el 68% de las muestras que tenemos son películas y el 32% de las muestras són series. Tal como hemos demostrado la mayoria de productos que nos ofrece netflix son peliculas.
sns.set(style="darkgrid")
ax = sns.countplot(x="type", data=netflix, palette="Set2")
Analizamos las classificaciones de las muestras que tenemos y las representamos en una gràfica. Este mètodo aplicado se llama "TV parental guideline" y es un sistema de clasificación de contenidos de televisión utilizado en los Estados Unidos. Estos són los diferentes tipos de classifiaciones para el público que dispone el dataset:
Para más información, se puede consultar el siguiente enlace: https://gopioneer.com/wp-content/uploads/2017/01/dtv_movieratings.pdf
Podemos observar en la gràfica como la mayoria de las muestras que tenemos pertenecen a estas dos destacadas classificiones TV-MA (enfocada para adultos y no menores de 17 años) y TV-14 (enfocado para adultos y no menores de 14 años).
plt.figure(figsize=(12,10))
sns.set(style="darkgrid")
ax = sns.countplot(x="rating", data=netflix, palette="Set2", order=netflix['rating'].value_counts().index[0:15])
Intentamos motrar la correlación entre los atributos pero como la mayoria de estos són de tipo texto, no podemos extraer conclusiones.
Este primer gráfico HetMap nos muestra la correlación entre los atributos numéricos y el segundo gráfico PairPlot tambien nos indica la correlación entre estos.
correlacio = netflix.corr()
plt.figure()
ax = sns.heatmap(correlacio, annot=True, linewidths=.5)
aux = pd.DataFrame(netflix)
relacio = sns.pairplot(aux)
Dado que los datos que tenemos en este dataset no nos permiten mostrar la correlación entre estos debido al formato que tienen. Se ha decido realizar un estudi más avanzado, separando el atributo "date_added" en dos "year_added" y "month_added", de esta manera podemos comprovar en que fechas a lo largo de los años y los meses, se han añadido más "productos" a Netflix.
Tambien se ha divido el atributo "duration" para que en caso de que sea una serie tengamos el atributo "season_count" y sepamos el número de temporadas que contiene, i en caso que sea una película podamos saber su tiempo de duración en el atributo "duration".
netflix["date_added"] = pd.to_datetime(netflix['date_added'])
netflix['year_added'] = netflix['date_added'].dt.year
netflix['month_added'] = netflix['date_added'].dt.month
netflix['season_count'] = netflix.apply(lambda x : x['duration'].split(" ")[0] if "Season" in x['duration'] else "", axis = 1)
netflix['duration'] = netflix.apply(lambda x : x['duration'].split(" ")[0] if "Season" not in x['duration'] else "", axis = 1)
netflix.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 6234 entries, 0 to 6233 Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 show_id 6234 non-null int64 1 type 6234 non-null object 2 title 6234 non-null object 3 director 4265 non-null object 4 cast 5664 non-null object 5 country 5758 non-null object 6 date_added 6223 non-null datetime64[ns] 7 release_year 6234 non-null int64 8 rating 6224 non-null object 9 duration 6234 non-null object 10 listed_in 6234 non-null object 11 description 6234 non-null object 12 year_added 6223 non-null float64 13 month_added 6223 non-null float64 14 season_count 6234 non-null object dtypes: datetime64[ns](1), float64(2), int64(2), object(10) memory usage: 730.7+ KB
d1 = netflix[netflix["type"] == "TV Show"]
d2 = netflix[netflix["type"] == "Movie"]
col = "year_added"
vc1 = d1[col].value_counts().reset_index()
vc1 = vc1.rename(columns = {col : "count", "index" : col})
vc1['percent'] = vc1['count'].apply(lambda x : 100*x/sum(vc1['count']))
vc1 = vc1.sort_values(col)
vc2 = d2[col].value_counts().reset_index()
vc2 = vc2.rename(columns = {col : "count", "index" : col})
vc2['percent'] = vc2['count'].apply(lambda x : 100*x/sum(vc2['count']))
vc2 = vc2.sort_values(col)
trace1 = go.Scatter(x=vc1[col], y=vc1["count"], name="TV Shows", marker=dict(color="#a678de"))
trace2 = go.Scatter(x=vc2[col], y=vc2["count"], name="Movies", marker=dict(color="#6ad49b"))
data = [trace1, trace2]
layout = go.Layout(title="Content added over the years", legend=dict(x=0.1, y=1.1, orientation="h"))
fig = go.Figure(data, layout=layout)
fig.show()
El gráfico anterior nos muestra la cantidad de contenido añadido a la plataforma Netflix a través de los años. Podemos observar como en 2013 empieza esta increment hasta llegar al punto más alto en año 2019 que se añadireon 1546 películas y 803 series.
col = "release_year"
vc1 = d1[col].value_counts().reset_index()
vc1 = vc1.rename(columns = {col : "count", "index" : col})
vc1['percent'] = vc1['count'].apply(lambda x : 100*x/sum(vc1['count']))
vc1 = vc1.sort_values(col)
vc2 = d2[col].value_counts().reset_index()
vc2 = vc2.rename(columns = {col : "count", "index" : col})
vc2['percent'] = vc2['count'].apply(lambda x : 100*x/sum(vc2['count']))
vc2 = vc2.sort_values(col)
trace1 = go.Bar(x=vc1[col], y=vc1["count"], name="TV Shows", marker=dict(color="#a678de"))
trace2 = go.Bar(x=vc2[col], y=vc2["count"], name="Movies", marker=dict(color="#6ad49b"))
data = [trace1, trace2]
layout = go.Layout(title="Content added over the years", legend=dict(x=0.1, y=1.1, orientation="h"))
fig = go.Figure(data, layout=layout)
fig.show()
El gráfico anterior, nos muestra la fecha de producción del contenido que disponemos en la plataforma. Observamos como la gran parte del contenido está producido entre el año 2015 y 2019. El pico más alto es en 2017 con 682 películas y en 2019 con 443 series. Podemos deducir que cada año que pasa se producen menos películas i se producen más series.
col = 'month_added'
vc1 = d1[col].value_counts().reset_index()
vc1 = vc1.rename(columns = {col : "count", "index" : col})
vc1['percent'] = vc1['count'].apply(lambda x : 100*x/sum(vc1['count']))
vc1 = vc1.sort_values(col)
trace1 = go.Bar(x=vc1[col], y=vc1["count"], name="TV Shows", marker=dict(color="#a678de"))
data = [trace1]
layout = go.Layout(title="In which month, the conent is added the most?", legend=dict(x=0.1, y=1.1, orientation="h"))
fig = go.Figure(data, layout=layout)
fig.show()
En este gráfico, podemos observar en que meses del año se suele añadir más contenido a la plataforma. Observamos como en el més de Diciembre es cuando más contenido se añade, esto puede sere debido a las época de Invierno y Navidades que al disponer de vacaciones o debido a las bajas temperaturas, se puede incitar más a los usuarios a consumir el contenido añadido. En cambio, el mes con menos contenido añadido es Febrero o los meses de Mayo y Junio.